﻿import ko = require("knockout");
import Track = require("Track");
import Editor = require("Editor");

class Project {
    public constructor(public editor: Editor, project?: EditoneLibRT.Project) {
        if (project) {
            this.project = project;
        } else {
            this.project = EditoneLibRT.Project.create();
        }
        this.refreshTracks();

        this.playbackMsec = ko.observable(this.project.playbackMsec);
        this.playbackState = ko.observable(this.project.playbackState);

        this.project.addEventListener("propertychanged", (prop: string) => { this.onPropertyChanged(prop); });
        this.project.addEventListener("settingschanged", (setting: string) => { this.onSettingsChanged(setting); });

        this.playbackMsec.subscribe((val) => this.project.playbackMsec = val);
    }

    project: EditoneLibRT.Project;

    tracks: KnockoutObservable<Track[]> = ko.observableArray([]);
    settings: {} = {};

    // In ticks (100 nanosecond intervals)
    maxTrackLength: KnockoutObservable<number> = ko.pureComputed(() => {
        var array = this.tracks();
        var max = 0;
        for (var i = 0; i < array.length; i++) {
            var track = array[i];
            var clips = track.clips();
            for (var j = 0; j < clips.length; j++) {
                var clip = clips[j];
                var end = clip.offset + clip.clip.duration();
                if (end > max) {
                    max = end;
                }
            }
        }
        return max;
    });

    createTrack(type: string, index: number = -1) {
        this.project.createTrack(type, index);
    }

    removeTrack(track: Track) {
        this.project.removeTrack(track.track);
    }

    private refreshTracks(): void {
        if (this.project.tracks === null) {
            this.tracks([]);
            return;
        }

        this.tracks(this.project.tracks.map((track) => {
            return new Track(this, track);
        }));
    }

    private onPropertyChanged(prop: string) {
        if (prop == "Tracks") {
            this.refreshTracks();
            return;
        }

        prop = prop.charAt(0).toLowerCase() + prop.slice(1);
        if (ko.isObservable(this[prop])) {
            this[prop](this.project[prop]);
        }
    }

    private onSettingsChanged(setting: string) {
        var obs: KnockoutObservable<Object> = this.settings[setting];
        if (obs === null) {
            this.settings[setting] = ko.observable(this.project.settings[setting]);
            return;
        }
        obs(this.project.settings[setting]);
    }
    playbackMsec: KnockoutObservable<number>;
    playbackState: KnockoutObservable<string>;
}

export = Project;